package simulaco.business;

import gminet.infra.business.BusinessException;
import gminet.infra.business.BusinessObject;
import gminet.infra.db.Transaction;
import gminet.infra.db.TransactionException;

import java.sql.Connection;
import java.util.ArrayList;
import java.util.List;

import simulaco.dao.ConcursoMateriaDAO;
import simulaco.dto.Concurso;
import simulaco.dto.ConcursoMateria;
import simulaco.dto.Materia;
import simulaco.dto.Situacao;

public class ConcursoMateriaBusiness extends BusinessObject {

    public static List<ConcursoMateria> findByConcurso(int concursoId) throws TransactionException {

        List<ConcursoMateria> concursoMaterias = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            concursoMaterias = ConcursoMateriaDAO.findByConcurso(concursoId, conn);
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return concursoMaterias;
    }

    protected static void updateAll(Concurso concurso, Connection conn) throws BusinessException, TransactionException {

        // VERIFICA OQ FOI INCLUIDO
        List<ConcursoMateria> concursoMateriasAtual = ConcursoMateriaDAO.findByConcurso(concurso.getCodigo(), conn);
        List<Materia> materiasNovo = new ArrayList<Materia>(concurso.getListaMateria());
        materiasNovo.removeAll(concursoMateriasAtual);
        // INCLUIR NOVOS
        for (Materia materia : materiasNovo) {
            int concursoId = concurso.getCodigo();
            int materiaId = materia.getCodigo();
            if (ConcursoMateriaDAO.findByPK(concursoId, materiaId, conn) == null) {
                ConcursoMateria concursoMateria = new ConcursoMateria();
                concursoMateria.setConcurso(concurso);
                concursoMateria.setMateria(materia);
                concursoMateria.setSituacao(Situacao.HABILITADO);
                ConcursoMateriaDAO.insert(concursoMateria, conn);
            }
        }
        // VERIFICA OQ FOI EXCLUIDO
        List<Materia> materiasExcluidas = new ArrayList<Materia>();
        for (ConcursoMateria concursoMateriaAtual : concursoMateriasAtual) {
            boolean achou = false;
            Materia materiaAtual = concursoMateriaAtual.getMateria();
            for (Materia materiaNovo : concurso.getListaMateria()) {
                if (materiaAtual.equals(materiaNovo)) {
                    achou = true;
                    break;
                }
            }
            if (!achou) {
                materiasExcluidas.add(materiaAtual);
            }
        }
        // EXCLUIR REMOVIDOS
        for (Materia materia : materiasExcluidas) {
            ConcursoMateria concursoMateria = new ConcursoMateria();
            concursoMateria.setConcurso(concurso);
            concursoMateria.setMateria(materia);
            if (ConcursoMateriaDAO.findByPK(concursoMateria, conn) != null) {
                ConcursoMateriaDAO.delete(concursoMateria, conn);
            }
        }
    }

    protected static void insertAll(Concurso concurso, Connection conn) throws BusinessException, TransactionException {

        List<Materia> materiasNovo = concurso.getListaMateria();
        // INCLUIR NOVOS
        for (Materia materia : materiasNovo) {
            int concursoId = concurso.getCodigo();
            int materiaId = materia.getCodigo();
            if (ConcursoMateriaDAO.findByPK(concursoId, materiaId, conn) == null) {
                ConcursoMateria concursoMateria = new ConcursoMateria();
                concursoMateria.setConcurso(concurso);
                concursoMateria.setMateria(materia);
                concursoMateria.setSituacao(Situacao.HABILITADO);
                ConcursoMateriaDAO.insert(concursoMateria, conn);
            }
        }
    }

    protected static void deleteByConcurso(Concurso concurso, Connection conn) throws BusinessException, TransactionException {

        ConcursoMateriaDAO.deleteByConcurso(concurso, conn);
    }

    public static ConcursoMateria insert(ConcursoMateria concursoMateria) throws BusinessException,
            TransactionException {

        ConcursoMateria newConcursoMateria = null;
        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            //
            if (ConcursoMateriaDAO.findByPK(concursoMateria, conn) != null) {
                throw new BusinessException("Matéria já cadastrada para esse concurso.");
            }
            // CONCURSO MATERIA
            concursoMateria.setSituacao(Situacao.HABILITADO);
            ConcursoMateriaDAO.insert(concursoMateria, conn);
            // COMMIT
            transaction.commit();
            //
            newConcursoMateria = concursoMateria;
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
        return newConcursoMateria;
    }

    public static void updateStatus(ConcursoMateria concursoMateria) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            ConcursoMateria auxConcursoMateria = ConcursoMateriaDAO.findByPK(concursoMateria, conn);
            auxConcursoMateria.setSituacao(concursoMateria.getSituacao());
            ConcursoMateriaDAO.update(auxConcursoMateria, conn);
            // COMMIT
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

    public static void delete(ConcursoMateria concursoMateria) throws BusinessException, TransactionException {

        Transaction transaction = createTransaction();
        try {
            Connection conn = transaction.getConnection();
            ConcursoMateriaDAO.delete(concursoMateria, conn);
            transaction.commit();
        } catch (TransactionException te) {
            transaction.rollback();
            throw te;
        } finally {
            transaction.release();
        }
    }

}
